#include "D20BaseModel.h"

D20BaseModel::D20BaseModel(QObject *parent) :
    ItemModel(parent)
{
}



void D20BaseModel::setRootItem(AbstractItem *root)
{
    ItemModel::setRootItem(root);
    initialize();
}



void D20BaseModel::initialize()
{
    if (!rootItem()) return;

    foreach (const int i, m_groups.keys())
    {
        if (groupIndex(i).isValid()) continue;
        int row = rowCount(QModelIndex());
        if (!insertRow(row, QModelIndex())) continue;


        QModelIndex nameIndex = index(row, AbstractItem::NameData, QModelIndex());
        setData(nameIndex, groupName(i), Qt::EditRole);
    }
}


void D20BaseModel::addGroup(const int& group, const QString& name)
{
    if (m_groups.contains(group) || m_groups.values().contains(name)) return;

    m_groups.insert(group, name);
}


QString D20BaseModel::groupName(const int& group) const
{
    return m_groups.value(group, QString());
}


int D20BaseModel::group(const QString& name) const
{
    return m_groups.key(name, -1);
}


QModelIndex D20BaseModel::groupIndex(const int& group) const
{
    if (!rootItem()) return QModelIndex();
    if (rootItem()->name().isEmpty()) rootItem()->setData(AbstractItem::NameData, "New Campaign Setting");

    QModelIndex searchIndex = index(0, AbstractItem::IdData, QModelIndex());
    QModelIndexList foundIndexes = match(searchIndex,
                                         Qt::EditRole,
                                         QString("%1.%2").arg(rootItem()->name()).arg(groupName(group)),
                                         1,
                                         Qt::MatchExactly);

    if (!foundIndexes.isEmpty()) return foundIndexes.first();


    return QModelIndex();
}



int D20BaseModel::addItem(const int& group, const QString& name)
{
    QModelIndex parent = groupIndex(group);
    if (!parent.isValid()) return -1;

    int row = rowCount(parent);
    if (!insertRow(row, parent)) return -1;

    QModelIndex idIndex = index(row, AbstractItem::IdData, parent);
    QModelIndex nameIndex = idIndex.sibling(idIndex.row(), AbstractItem::NameData);

    setData(nameIndex, name);
    return row;
}



bool D20BaseModel::removeItem(const int& group, const int& item)
{
    QModelIndex index = groupIndex(group);
    blockSignals(true);
    bool ret = removeRow(item, index);
    blockSignals(false);

    QModelIndexList indexList = itemIndexes(group);
    if (indexList.isEmpty()) emit dataChanged(index, index);
    else                     emit dataChanged(index, indexList.last());

    return ret;
}



bool D20BaseModel::removeItem(const int& group, const QString& name)
{
    QModelIndexList indexList = itemIndexes(group);
    bool ret = false;
    foreach (QModelIndex index, indexList)
    {
        if (!index.data(Qt::EditRole).toString().toLower().endsWith(name.toLower())) continue;

        ret = removeRow(index.row(), index.parent());
        break;
    }

    QModelIndex parent = groupIndex(group);
    indexList = itemIndexes(group);
    if (indexList.isEmpty()) emit dataChanged(parent, parent);
    else                     emit dataChanged(parent, indexList.last());

    return ret;
}


QModelIndexList D20BaseModel::itemIndexes(const int& group) const
{
    // this also checks root existence
    QModelIndex parent = groupIndex(group);
    if (!parent.isValid()) return QModelIndexList();

    QModelIndex search = index(0, AbstractItem::IdData, parent);
    return match(search,
                 Qt::EditRole,
                 QString("%1.%2").arg(rootItem()->name()).arg(groupName(group)),
                 -1,
                 Qt::MatchStartsWith);
}



Qt::ItemFlags D20BaseModel::flags(const QModelIndex &index) const
{
    QModelIndex nameIndex = index.sibling(index.row(), AbstractItem::NameData);
    if (group(nameIndex.data().toString()) == -1) return ItemModel::flags(index);

    return QAbstractItemModel::flags(index);
}


